package org.jeecg.modules.achexamination.service.impl;

import cn.hutool.core.date.DateTime;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Param;
import org.checkerframework.checker.units.qual.A;
import org.jeecg.modules.achachievementstandard.entity.AchAchievementStandard;
import org.jeecg.modules.achachievementstandard.service.IAchAchievementStandardService;
import org.jeecg.modules.achachievementstandard.service.impl.AchAchievementStandardServiceImpl;
import org.jeecg.modules.achachievestandarditem.entity.AchAchieveStandardItem;
import org.jeecg.modules.achachievestandarditem.service.IAchAchieveStandardItemService;
import org.jeecg.modules.achexamination.controller.AchExaminationController;
import org.jeecg.modules.achexamination.entity.AchExamination;
import org.jeecg.modules.achexamination.mapper.AchExaminationMapper;
import org.jeecg.modules.achexamination.service.IAchExaminationService;
import org.jeecg.modules.achexamination.vo.AchExaminationVo;
import org.jeecg.modules.achexaminationpaper.controller.AchExaminationPaperController;
import org.jeecg.modules.achexaminationpaper.entity.AchExaminationPaper;
import org.jeecg.modules.achexaminationpaper.service.IAchExaminationPaperService;
import org.jeecg.modules.relation.relachstandarddistribution.entity.RelAchStandardDistribution;
import org.jeecg.modules.relation.relachstandarddistribution.service.IRelAchStandardDistributionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @Description: ach_examination
 * @author: baochangrong
 * @Date: 2022-03-15
 * @Version: V1.0
 */
@Service
public class AchExaminationServiceImpl extends ServiceImpl<AchExaminationMapper, AchExamination> implements IAchExaminationService {

    @Autowired
    AchExaminationMapper achExaminationMapper;

    @Autowired
    IAchExaminationPaperService examinationPaperService;

    @Autowired
    IRelAchStandardDistributionService distributionService;

    @Autowired
    IAchAchievementStandardService standardService;

    @Autowired
    IAchAchieveStandardItemService itemService;

    @Autowired
    AchExaminationPaperController paperController;

    /**
     * 获取所有考试数据 分页查询
     */
    @Override
    public IPage<AchExaminationVo> getAchExaminationList(Page<AchExaminationVo> page, @Param("achExaminationVo") AchExaminationVo achExaminationVo) {
        List<AchExaminationVo> achExaminationVoList = achExaminationMapper.getAchExaminationList(page, achExaminationVo);
        return page.setRecords(achExaminationVoList);
    }

    @Override
    public List<String> getExaminationByExamId(String examId) {
        return achExaminationMapper.getExaminationByExamId(examId);
    }

    @Transactional(rollbackFor = RuntimeException.class)
    @Override
    public boolean copyExamination(String json) {
        JSONObject object = JSON.parseObject(json);
        JSONObject newExamInfo = object.getJSONObject("newExamInfo");
        String startTime = object.getString("startTime");
        System.out.println(object.getDate(startTime));
        AchExamination exam = newExamInfo.toJavaObject(AchExamination.class);
        // 试卷科目 规则 评分标准
        String oldExamId = exam.getId();
        //试卷
        List<AchExaminationPaper> papers = examinationPaperService.queryAllByExamId(oldExamId);
        //查询关系
        List<RelAchStandardDistribution> distributions = distributionService.queryAllByObjId(oldExamId);
        //查询Standard;
        ArrayList<String> ids = new ArrayList<>(distributions.size());
        if (distributions.size() > 0) {
            distributions.forEach(item -> {
                ids.add(item.getAchievementStandardId());
                item.setId(null)
                        .setCreateTime(null);
            });
        }
        List<AchAchievementStandard> standards = standardService.listByIds(ids);
        //查询item
        ArrayList<String> standardIds = new ArrayList<>();
        standards.forEach(item -> {
            standardIds.add(item.getId());
        });
        List<AchAchieveStandardItem> standardItems = itemService.list(new LambdaQueryWrapper<AchAchieveStandardItem>()
                .eq(AchAchieveStandardItem::getDelFlag, 0)
                .in(AchAchieveStandardItem::getAchievementStandardId, standardIds));
        ids.clear();
        standardIds.clear();

        return saveObjectLists(exam, papers, distributions, standards, standardItems, startTime);
    }

    /**
     * Insert into Database
     *
     * @param papers        Examination Paper List
     * @param distributions Rel-Standard-Distribution List
     * @param standards     Standard List
     * @param standardItems Standard Items List
     * @return success or un-success
     */
    protected boolean saveObjectLists(AchExamination newExam, List<AchExaminationPaper> papers, List<RelAchStandardDistribution> distributions, List<AchAchievementStandard> standards, List<AchAchieveStandardItem> standardItems, String examStartTime) {
        try {
            Date date = new SimpleDateFormat("yyyy-MM-dd").parse(examStartTime);
            if (papers.size() != 0 && distributions.size() != 0 && standards.size() != 0) {
                List<AchExaminationPaper> insertExamExaminationPapers = papers.stream().filter(s -> s.getExaminationId().equals(newExam.getId())).collect(Collectors.toList());
                save(newExam
                        .setId(null)
                        .setCreateBy(null)
                        .setCreateTime(null)
                        .setUpdateBy(null)
                        .setCreateTime(null));
                insertExamExaminationPapers.forEach(paper -> {
                    paper.setExaminationId(newExam.getId());
                    if (date != null) {
                        paper.setExaminationPaperTestTime(date);
                    }
                    examinationPaperService.copyAchExaminationPaper(paper);
                });
                standards.forEach(standard -> {
                    List<AchAchieveStandardItem> insertStandardItemList = standardItems.stream()
                            .filter(s -> s.getAchievementStandardId().equals(standard.getId()))
                            .collect(Collectors.toList());
                    List<RelAchStandardDistribution> insertDistributionList = distributions.stream()
                            .filter(distribution -> distribution.getAchievementStandardId().equals(standard.getId()))
                            .collect(Collectors.toList());
                    standard.setId(null)
                            .setUpdateBy(null)
                            .setUpdateTime(null);
                    standardService.save(standard);
                    insertStandardItemList.forEach(insertStandardItem -> {
                        insertStandardItem.setId(null)
                                .setAchievementStandardId(standard.getId())
                                .setCreateBy(null)
                                .setCreateTime(null)
                                .setUpdateBy(null)
                                .setUpdateTime(null);
                    });
                    itemService.saveBatch(insertStandardItemList);
                    insertDistributionList.forEach(distribution -> {
                        distribution.setId(null)
                                .setAchievementStandardId(standard.getId())
                                .setRelObjId(newExam.getId())
                                .setCreateTime(null);
                    });
                    distributionService.saveBatch(insertDistributionList);
                });
                return true;
            }
        } catch (Exception e) {
            log.error("Save Data is Wrong ... " + e.getMessage());
            throw new RuntimeException();
        }
        return false;
    }
}
